#include "comm.hpp"
// 对应的程序，在加载的时候自动构建全局变量，自动调用构造函数--创建了管道
// 程序退出时，自动调用析构函数--删除了管道文件
Init init; // 定义全局变量，类型为Init
string TransToHex(key_t k)
{
    char buffer[32];
    snprintf(buffer, sizeof(buffer), "0x%x", k);
    return buffer;
}

int main()
{
    // 1.创建公共的key值
    key_t k = ftok(PATH_NAME, PROJ_ID);
    assert(k != -1);
    Log("create key done", Debug) << "server key : " << k << endl;

    // 2.创建共享内存
    int shmid = shmget(k, SHM_SIZE, IPC_CREAT | IPC_EXCL | 0666); // 这里0666是创建共享内存后该共享内存的权限
    if (shmid == -1)
    {
        perror("shmget");
        exit(1);
    }
    Log("create shm done", Debug) << "shmid : " << shmid << endl;
    // sleep(10);

    // 3.将指定的共享内存挂接到自己的地址空间
    char *shmaddr = (char *)shmat(shmid, nullptr, 0);
    Log("attach shm done", Debug) << "shmid : " << shmid << endl;
    //    sleep(10);

    // 这里就是通信的逻辑
    // 把共享内存当成字符串
    int fd = OpenFIFO(FIFO_NAME, READ); // 打开创建的管道文件

    char buffer[SHM_SIZE];
    for (;;)
    {
        Wait(fd);
        // 整段程序中，只有这两行代码是访问共享内存的，
        // 我们把它叫做临界区
        printf("%s\n", shmaddr);
        if (strcmp(shmaddr, "quit") == 0)
            break;
        // sleep(1);
    }

    // 4. 将指定的共享内存，从自己的地址空间中去关联(就是去掉页表中的共享内存映射关系)
    int n = shmdt(shmaddr);
    assert(n != -1);
    (void)n;
    Log("detach shm done", Debug) << "shmid : " << shmid << endl;
    // sleep(10);

    // last.删除共享内存
    n = shmctl(shmid, IPC_RMID, nullptr);
    assert(n != -1);
    (void)n;
    Log("delete shm done", Debug) << "shmid : " << shmid << endl;

    CloseFifo(fd);
    return 0;
}